package org.linlinjava.litemall.db.service;

import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallOrderMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.distribution.DisMemberAmountService;
import org.linlinjava.litemall.db.service.distribution.DisMemberInfoService;
import org.linlinjava.litemall.db.service.distribution.DisProfitParamService;
import org.linlinjava.litemall.db.service.distribution.DisProfitRecordService;
import org.linlinjava.litemall.db.util.DateTools;
import org.linlinjava.litemall.db.util.IdUtil;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.beans.Transient;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Service
public class LitemallOrderService {
    @Resource
    private LitemallOrderMapper orderMapper;
    @Autowired
    private DisProfitParamService paramService;
    @Autowired
    private DisMemberAmountService memberAmountService;
    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    @Autowired
    private LitemallUserService userService;
    @Autowired
    private DisMemberInfoService memberService;
    @Autowired
    private DisProfitRecordService recordService;

    public int add(LitemallOrder order) {
        return orderMapper.insertSelective(order);
    }

    public List<LitemallOrder> query(Integer userId) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public int count(Integer userId) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    public LitemallOrder findById(Integer orderId) {
        return orderMapper.selectByPrimaryKey(orderId);
    }

    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public LitemallOrder queryByOrderSn(Integer userId, String orderSn) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return orderMapper.selectOneByExample(example);
    }

    public LitemallOrder queryByOrderSn(String orderSn) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return orderMapper.selectOneByExample(example);
    }

    public int countByOrderSn(Integer userId, String orderSn) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    public String generateOrderSn(Integer userId) {

   /*     DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
        String now = df.format(LocalDate.now());
        String orderSn = now + getRandomNum(6);
        while(countByOrderSn(userId, orderSn) != 0){
            orderSn = getRandomNum(6);
        }*/
        return IdUtil.getId();
    }

    public List<LitemallOrder> queryByOrderStatus(Integer userId, List<Short> orderStatus) {
        LitemallOrderExample example = new LitemallOrderExample();
        example.orderBy(LitemallOrder.Column.addTime.desc());
        LitemallOrderExample.Criteria criteria = example.or();
        criteria.andUserIdEqualTo(userId);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public int countByOrderStatus(Integer userId, List<Short> orderStatus) {
        LitemallOrderExample example = new LitemallOrderExample();
        LitemallOrderExample.Criteria criteria = example.or();
        criteria.andUserIdEqualTo(userId);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    public int update(LitemallOrder order) {

        return orderMapper.updateByPrimaryKeySelective(order);
    }

    public List<LitemallOrder> querySelective(Integer page, Integer size, LitemallOrder order) {
        LitemallOrderExample example = new LitemallOrderExample();
        LitemallOrderExample.Criteria criteria = example.createCriteria();

        if (order.getUserId() != null) {
            criteria.andUserIdEqualTo(order.getUserId());
        }
        if (!StringUtils.isEmpty(order.getOrderSn())) {
            criteria.andOrderSnEqualTo(order.getOrderSn());
        }
        if (!StringUtils.isEmpty(order.getOrderStatus())) {
            criteria.andOrderStatusEqualTo(order.getOrderStatus());
        }
        if (!StringUtils.isEmpty(order.getConsignee())) {
            criteria.andConsigneeLike("%" + order.getConsignee() + "%");
        }
        if (!StringUtils.isEmpty(order.getMobile())) {
            criteria.andMobileLike("%" + order.getMobile() + "%");
        }
        criteria.andDeletedEqualTo(false);
        example.orderBy(LitemallOrder.Column.orderStatus.asc(), LitemallOrder.Column.addTime.desc());
        PageHelper.startPage(page, size);
        return orderMapper.selectByExample(example);
    }

    public int countSelective(Integer page, Integer size, LitemallOrder order) {
        LitemallOrderExample example = new LitemallOrderExample();
        LitemallOrderExample.Criteria criteria = example.createCriteria();


        if (order.getUserId() != null) {
            criteria.andUserIdEqualTo(order.getUserId());
        }
        if (!StringUtils.isEmpty(order.getOrderSn())) {
            criteria.andOrderSnEqualTo(order.getOrderSn());
        }
        if (!StringUtils.isEmpty(order.getOrderStatus())) {
            criteria.andOrderStatusEqualTo(order.getOrderStatus());
        }
        if (!StringUtils.isEmpty(order.getConsignee())) {
            criteria.andConsigneeLike("%" + order.getConsignee() + "%");
        }
        if (!StringUtils.isEmpty(order.getMobile())) {
            criteria.andMobileLike("%" + order.getMobile() + "%");
        }
        criteria.andDeletedEqualTo(false);

        return (int) orderMapper.countByExample(example);
    }

    public void updateById(LitemallOrder order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    public void deleteById(Integer id) {
        LitemallOrder order = orderMapper.selectByPrimaryKey(id);
        if (order == null) {
            return;
        }
        order.setDeleted(true);
        orderMapper.updateByPrimaryKey(order);
    }

    public int count() {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    public List<LitemallOrder> queryUnpaid() {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public List<LitemallOrder> queryUnconfirm() {
        LitemallOrderExample example = new LitemallOrderExample();
        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_SHIP).andShipEndTimeIsNotNull().andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public List<LitemallOrder> queryByEnd(Integer userId) {
        LitemallOrderExample example = new LitemallOrderExample();
        LitemallOrderExample.Criteria criteria = example.createCriteria();

        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        List<Short> list = new ArrayList<>();
        list.add(OrderUtil.STATUS_CONFIRM);
        list.add(OrderUtil.STATUS_AUTO_CONFIRM);
        criteria.andOrderStatusIn(list);
        criteria.andDeletedEqualTo(false);
        example.orderBy(LitemallOrder.Column.addTime.desc());
        return orderMapper.selectByExample(example);
    }

    public void distribute(LitemallOrder order) {


        order = orderMapper.selectByPrimaryKey(order.getId());
        //二级总价
        BigDecimal tAmount = new BigDecimal(0);
        //一级总价
        BigDecimal oAmount = new BigDecimal(0);

        BigDecimal hud = new BigDecimal(100);
        //该用户是否是经销商用户
        LitemallUser user = userService.findById(order.getUserId());
        if(user!=null && !"经销商用户".equals(user.getUserLevel())){
            user.setUserLevel("经销商用户");
            userService.update(user);
        }
        //獲取訂單商品数量
        List<LitemallOrderGoods> orderGoods = orderGoodsService.queryByOid(order.getId());
        for (LitemallOrderGoods g : orderGoods) {
            DisProfitParam param = paramService.getByGoodsId(g.getGoodsId());
            if(param!=null){
                if (DisProfitParam.MODEL_AVG.equals(param.getDisProMode())) {
                    double o = new Double(param.getDisProValue())/100;
                    double t = new Double(param.getDisProLevel()) / 100;
                    oAmount = oAmount.add(g.getRetailPrice().multiply(new BigDecimal(o))
                            .multiply(new BigDecimal(g.getNumber())));
                    tAmount = tAmount.add(g.getRetailPrice().multiply(new BigDecimal(t))
                            .multiply(new BigDecimal(g.getNumber())));
                } else {
                    oAmount = oAmount.add(new BigDecimal(param.getDisProValue() * g.getNumber()));
                    tAmount = tAmount.add(new BigDecimal(Integer.parseInt(param.getDisProLevel() == null ? "0" : param.getDisProLevel()) * g.getNumber()));
                }
            }
        }
        //设置上级会员分成  上线为二层  上线的上线为一层
        DisMemberInfo memberInfo = memberService.getByUserId(order.getUserId());
        String two = "3";
        if (!StringUtils.isEmpty(memberInfo.getDisModelId())) {
            two = memberInfo.getDisModelId();
        }
        if (memberInfo != null) {
            memberInfo.setType(DisMemberInfo.TYPE_Y);
            memberService.update(memberInfo);
            //上线分润
            DisMemberAmount parent = memberAmountService.getByuserId(Integer.parseInt(two));

            //先进性二级分润，然后查询是否有一级分润
            share(parent, order, tAmount, "2",two);
            //二层用户
            DisMemberInfo member2 = null;
            if(!StringUtils.isEmpty(memberInfo.getDisModelId()) ){
                member2 = memberService.getByUserId(Integer.parseInt(memberInfo.getDisModelId()));
            }

            if (member2 !=null && !StringUtils.isEmpty(member2.getDisModelId())) {
                //一层用户账户
                DisMemberAmount parent2 = memberAmountService.getByuserId(Integer.parseInt(member2.getDisModelId()));
                if (parent2 != null) {
                    share(parent2, order, oAmount, "1",member2.getDisModelId());
                }
            }
        }
    }

    /**
     * 具体分润方式
     *
     * @param parent
     * @param order
     * @param amount
     * @param proType
     */
    public void share(DisMemberAmount parent, LitemallOrder order, BigDecimal amount, String proType,String parentId) {

        String current = DateTools.getCurrentSysData(DateTools.FULLTIME_FORMAT);
        if(parent==null){
            parent = new DisMemberAmount();
            LitemallUser user = userService.findById(Integer.valueOf(parentId));
            parent.setDisUserId(parentId);
            parent.setDisUserName(user.getNickname());
            parent.setAddTime(current);
            parent.setUpdateTime(current);

            parent.setTotalAmount(amount);
            parent.setAvaibleAmount(amount);

            memberAmountService.insert(parent);
        }else{
            //可用金额和总金额
            parent.setTotalAmount(parent.getTotalAmount().add(amount));
            parent.setAvaibleAmount(parent.getAvaibleAmount().add(amount));
            parent.setUpdateTime(current);
            memberAmountService.update(parent);
        }
            //设置分销记录
            DisProfitRecord record = new DisProfitRecord();
            record.setAddTime(current);
            record.setUpdateTime(current);
            record.setDisGetUserId(parent.getDisUserId());
            record.setDisSetUserId(order.getUserId().toString());
            record.setDisAmount(amount);
            record.setDisOrderId(order.getOrderSn());
            record.setDisProType(proType);
            record.setIsDelete("N");
            recordService.insert(record);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateRev(LitemallOrder order) {
        orderMapper.updateByPrimaryKeySelective(order);
        if(OrderUtil.STATUS_AUTO_CONFIRM.equals(order.getOrderStatus())||OrderUtil.STATUS_CONFIRM.equals(order.getOrderStatus())){
            this.distribute(order);
        }
    }

    /**
     * 微信收货
     * @param order
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateByWX(LitemallOrder order) {
        orderMapper.updateByPrimaryKeySelective(order);
         this.distribute(order);
    }

    public static void main(String[] args) {
        double o = new Double(31)/100;
        double t =  new Double("9") / 100;
        System.out.println(222);
    }

}
